"""Contains classes for tests for basic demonstration of tool."""


class Base:
    """Base class with a few attributes and couple methods."""

    base_attr = 'Attribute og base class'

    def first_method(self):
        """Method to be inherited."""
        print('1th method of Base')
        return 1

    def second_method(self):
        """Method to be overidden."""
        print('2th method of Base, not implemented')
        raise NotImplementedError

from functools import wraps

def decorator(function):
    # XXX: without this there will be bugs!!!
    @wraps(function)
    def wrapper(*args, **kwargs):
        return function(*args, **kwargs)
    return wrapper

class Mixin:
    """Mixin class to override stub method from base class."""

    @decorator
    def second_method(self):
        """Implement base's stub function."""
        print('3th method of Mixin')
        return 2


class Example(Mixin, Base):
    """Class with inheritance."""

    attr = '1st attribute of Example'

    def __init__(self, one=None):
        self.one = one

    def third_method(self):
        """Method defined right here, not inherited, not overriden."""
        print('3th method of Ex3')
        return 3


class Example2(Base, Mixin):

    attr = '1st attribute of Example2'

    def third_method(self):
        print('4th method of Ex2')
        return 4


class Example3(Base, Mixin):

    attr = '1st attr of Ex3 class'

    def fourth_method(self):
        print('4th method of Ex3')
        return 4


class MethodHolder:
    """Do not change anything in this class!
    This is the class which holds single method."""

    def call_me(self):
        """What is my crc32?"""
        print("You've did it!")


# detect overriden __init__ method

class WithCustomInit:
    """Define custom init function"""

    def __init__(self, one=1):
        """Get one argument"""
        self.one = one

class InheritCustomInit(WithCustomInit):
    """The __init__ method should not be listed."""


class OverrideCustomInit(WithCustomInit):
    """The __init__ method should be listed, because it's overriden."""

    def __init__(self, one=2):
        """Overriden __init__ method"""
        self.one = one + 1
